# !/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time : 2023/8/25 19:22
# @Author : xyjiang1216
# @Email : jiangxuyan@nudt.edu.cn
# @File : patch.py
# @Version: OpenPlanner2.0
import json

from OpenPlanner.util.compute_hyper_period import compute_hyper_period


def solution_transform(solution_file,
                       stream_obj_set,
                       link_obj_set
                       # st_queues=2,
                       # macrotick=125,
                       # hyper_period=20000,
                       # # 需要知道报文长度和链路速率
                       # trans_delay=125
                       ):
    macrotick = link_obj_set[0].macrotick
    hyper_period = compute_hyper_period(
        *[stream_obj.period for stream_obj in \
          stream_obj_set]
    )
    trans_delay = 0
    if macrotick >= 13:
        trans_delay = macrotick
    else:
        # TODO: trans_delay的计算
        print('待补充')

    solution = []
    # mapping = []
    with open(solution_file) as fd:
        # 第一行：======
        line = fd.readline()
        while line:
            line = fd.readline()
            # line = line.split()
            if "offset and prio set" in line:
                link_set = {"link_id": 0,
                            "gcl_entries": []}
                # map_set = {"link_id": 0,
                #            "map_entries": []}
                link_id = line.split()[-1]
                link_set["link_id"] = link_id
                # map_set["link_id"] = link_id
                # 第三行：----
                line = fd.readline()
                line_offset = fd.readline()
                line_prio = fd.readline()
                while line == '---------------------------------------------------|\n' \
                        and line_offset != '\n':
                    # line = fd.readline()
                    # line_offset = fd.readline()
                    # print(line_offset)
                    # line_prio = fd.readline()
                    # print(line_prio)
                    stream_id = line_offset.split()[1].split('_')[1].split('^')[0]
                    # print(stream_id)
                    offset = line_offset.split()[-2]
                    prio = line_prio.split()[-2]

                    link_set["gcl_entries"].append([int(offset),
                                                    int(prio),
                                                    int(stream_id)])

                    # period = stream_obj_set[int(stream_id)].period
                    # for instance in range(int(hyper_period / period)):
                    #     link_set["gcl_entries"].append([int(offset) + int(instance * period / macrotick),
                    #                                     int(prio)])
                    # map_set["map_entries"].append({"stream_id": int(stream_id),
                    #                                "queue_id": int(prio)})

                    line = fd.readline()
                    line_offset = fd.readline()
                    line_prio = fd.readline()
                solution.append(link_set)
                # mapping.append(map_set)
    for entry in solution:
        gcl_entries = entry['gcl_entries']
        gcl_entries.sort(key=lambda x: x[0])
        entry['gcl_entries'] = gcl_entries

    link_id = 0
    for entry in solution:
        st_queues = link_obj_set[link_id].st_queues
        gcl_entries = entry['gcl_entries']
        start = 0
        new_gcl_entries = []
        for gcl_entry in gcl_entries:
            offset = int(gcl_entry[0])
            prio = int(gcl_entry[1])
            stream_id = int(gcl_entry[2])
            if offset * macrotick - start != 0:
                dic = {"interval": offset * macrotick - start,
                       "state": '0b00',
                       "stream_id": 'none'}
                new_gcl_entries.append(dic)
            o_bin = bin(0b01 << prio)[2:]  # 转换为二进制，并且去掉“0b”
            out_bin = o_bin.rjust(st_queues, '0')  # 原字符串右侧对齐， 左侧补零，补齐后总位宽为8 #不带"0b"
            out_bin = "0b" + out_bin  # 带"0b"，和python内置函数bin输出格式一致，字符串开头带"0b"
            dic = {"interval": trans_delay,
                   "state": out_bin,
                   "stream_id": stream_id}
            new_gcl_entries.append(dic)
            start = offset * macrotick + trans_delay
        if start != hyper_period:
            dic = {"interval": hyper_period - start,
                   "state": '0b00',
                   "stream_id": 'none'}
            new_gcl_entries.append(dic)
        entry['gcl_entries'] = new_gcl_entries

        link_id += 1


    # 将 Python 列表转换为 json 格式
    # indent 参数用于美观的格式化 json 数据
    # ensure_ascii=False 防止乱码
    json_data = json.dumps(solution, ensure_ascii=False, indent=4)

    # 将 json 数据写入文件
    # print(solution_file)
    with open(solution_file.split('.json')[0] + '_gcl.json', "w", encoding='utf-8') as file:
        file.write(json_data)

    # json_data = json.dumps(mapping, ensure_ascii=False, indent=4)
    # with open(solution_file.split('.json')[0] + '_map.json', "w", encoding='utf-8') as file:
    #     file.write(json_data)
    # pass


if __name__ == '__main__':
    solution_transform("temp/20230829_154204solution_demo.json",
                       )
